// import * as Cesium from 'cesium'
import MarkerStyle from '../style/MarkerStyle'
import mitt from 'mitt'
import {EVENT_TYPE} from "@/utils/eventBus";

let originPosition = 0
/**
 * 标记（贴地）
 */
export default class Marker {
  // 实体类型
  static ENTITY_TYPE = {
    POINT: 'point',
    BILLBOARD: 'billboard'
  }

  // 订阅消息类型
  static EVENT_TYPE = {
    MOVE_END: 'moveEnd'
  }
  /**
   * 渲染点，并且点会自动贴合到模型表面
   * 注意： 如果需要贴合模型表面, 需要等模型加载完之后才能调用本方法,加载完成事件详见 onLoaded
   * @param longitude 经度(required)
   * @param latitude 纬度(required)
   * @param height 高度(米) 不传或者传null、undefined时，自动贴合到模型表面
   * @param id 唯一id
   * @param imgUrl 图标
   * @param imgWidth 图标宽
   * @param style 样式属性，详见MarkerStyle
   * @param viewer
   */
  constructor(options) {
    const { viewer, id, longitude, latitude, height, style } = options || {}
    this.id = id
    this.viewer = viewer
    this.longitude = longitude
    this.latitude = latitude
    this.positionArr = ref([])
    this.height = height
    this.lerpValue = 75
    this.isMoveEnd = true
    this.emitter = mitt()
    this.emitter.emit(Marker.EVENT_TYPE.MOVE_END)
    // 触发的一个标识
    this.emitter.on(Marker.EVENT_TYPE.MOVE_END, () => {
      console.log('收到完成移动事件')
      this.isMoveEnd = true
    })
    this.isMoving = false // 改变位置时，是否正在执行
    const { iconStyle, textStyle } = style || new MarkerStyle()
    this.marker = viewer.entities.add({
      id,
      billboard: {
        image: iconStyle.url,
        width: iconStyle.width,
        height: iconStyle.height,
        pixelOffset: iconStyle.pixelOffset,
        scaleByDistance: new Cesium.NearFarScalar(6.5e2, 1.0, 3e3, 0),
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM
      },
      label: {
        text: textStyle.text,
        font: textStyle.font,
        fillColor: textStyle.fillColor,
        outlineColor: textStyle.outlineColor,
        outlineWidth: textStyle.outlineWidth,
        showBackground: textStyle.showBackground,
        backgroundColor: textStyle.backgroundColor,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        horizontalOrigin: textStyle.horizontalOrigin,
        // 垂直方向以底部来计算标签的位置
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        scaleByDistance: new Cesium.NearFarScalar(6.5e2, 1.0, 6.5e2, 0),
        // 偏移量
        pixelOffset: textStyle.pixelOffset
      },
      clampToGround: true
    })
    let fromDegrees = null
    if (height) {
      fromDegrees = new Cesium.Cartesian3.fromDegrees(longitude, latitude, height)
    } else {
      fromDegrees = this.viewer.scene.clampToHeight(Cesium.Cartesian3.fromDegrees(longitude, latitude))
    }
    this.startPosition = fromDegrees
    this.marker.position = fromDegrees
    originPosition = this.marker.position
  }

  /**
   * 更新点位置
   * @param longitude 经度（度）(required)
   * @param latitude 纬度（度）(required)
   * @param height 高度(米) 不传或者传null、undefined时，自动贴合到模型表面
   */
  updatePosition({ longitude, latitude, height }, isAnimation = true) {
    this.longitude = longitude
    this.latitude = latitude
    this.height = height
    let fromDegrees = null
    if (height) {
      fromDegrees = Cesium.Cartesian3.fromDegrees(longitude, latitude, height)
      // console.log('有高度设置Car3:', fromDegrees)
    } else {
      fromDegrees = this.viewer.scene.clampToHeight(Cesium.Cartesian3.fromDegrees(longitude, latitude))
      // console.log('无高度设置Car3:', fromDegrees)
    }
    this.moveTo(fromDegrees, isAnimation)
  }

  /**
   * 移动到某个点
   * @param position 点位置
   * @param animation 是否开启动画平移
   */
  moveTo(position, animation = false, isSend = true) {
    // 如果点不存在或者移动后的点和当前点一样，则不操作
    if (!this.marker || JSON.stringify(this.startPosition) === JSON.stringify(position)) {
      console.log('如果点不存在或者移动后的点和当前点一样，则不操作')
      return
    }
    if (!animation) {
      this.marker.position = position
      return
    }
    if (isSend) {
      this.positionArr.value.push(position)
      console.log('往位置数组中插入', this.positionArr.value)
    }
    if (this.isMoving) {
      console.log('再次来数据，此时没有完成移动')
      return
    }

    // 插值的数量
    let factor = 0
    this.isMoving = true
    const t = Date.now()
    this.isMoveEnd = false
    this.marker.position = new Cesium.CallbackProperty(() => {
      if (factor >= this.lerpValue) {
        if (!this.isMoveEnd) {
          console.log('触发动画结束事件，动画执行时长：' + (Date.now() - t) + 'ms')
          this.isMoving = false
          this.startPosition = this.positionArr.value[0]
          console.log('startPostion=', this.startPosition, this.positionArr.value)
          this.positionArr.value = this.positionArr.value.slice(1)
          console.log('剔除头后的数组，', this.positionArr.value)
          this.emitter.emit(Marker.EVENT_TYPE.MOVE_END)
          if (this.positionArr.value.length > 0) {
            this.moveTo(this.positionArr.value[0], true, false)
          }
        }
        return position
      }
      factor++
      // 动态更新位置
      return Cesium.Cartesian3.lerp(this.startPosition, position, factor / this.lerpValue, new Cesium.Cartesian3())
    }, false)




  }
  /**
   * 设置位置
   */
  setCooridinate() {
    this.marker.position = new Cesium.CallbackProperty(function () {
      return originPosition
    }, false)
  }

  /**
   * 设置样式
   * @param style 样式属性，详见MarkerStyle
   */
  setStyle(style) {
    const { iconStyle, textStyle } = style || new MarkerStyle()
    this.marker.billboardimage = iconStyle.url
    this.marker.billboardwidth = iconStyle.width
    this.marker.billboardheight = iconStyle.height
    this.marker.billboardpixelOffset = iconStyle.pixelOffset
    this.marker.label.text = textStyle.text
    this.marker.label.font = textStyle.font
    this.marker.label.fillColor = textStyle.fillColor
    this.marker.label.outlineColor = textStyle.outlineColor
    this.marker.label.outlineWidth = textStyle.outlineWidth
    this.marker.label.showBackground = textStyle.showBackground
    this.marker.label.backgroundColor = textStyle.backgroundColor
    this.marker.label.pixelOffset = textStyle.pixelOffset
  }

  /**
   * 设置图标样式
   * @param iconStyle
   */
  setIconStyle(iconStyle) {
    this.marker.billboardimage = iconStyle.url
    this.marker.billboardwidth = iconStyle.width
    this.marker.billboardheight = iconStyle.height
    this.marker.billboardpixelOffset = iconStyle.pixelOffset
  }

  /**
   * 设置字体样式
   * @param textStyle
   */
  setTextStyle(textStyle) {
    this.marker.label.fillColor = textStyle.fillColor
    this.marker.label.outlineColor = textStyle.outlineColor
    this.marker.label.outlineWidth = textStyle.outlineWidth || 4
  }

  /**
   * 设置Marker是否可见
   * @param bool visibility
   */
  setVisible(visibility) {
    this.marker.billboard.show = visibility
    this.marker.label.show = visibility
  }

  /**
   * 从场景中删除该标记
   */
  remove() {
    this.positionArr.value.length = 0
    this.viewer.entities.remove(this.marker)
  }
  /**
   * 订阅位置移动状态
   */
  addListener(eventName, callback) {
    if (!Object.values(Marker.EVENT_TYPE).includes(eventName)) {
      return
    }
    this.emitter.on(eventName, callback)
  }

  /**
   * 取消订阅
   * @param eventName 事件名，为空时全部取消
   */
  removeListener(eventName) {
    if (eventName) {
      this.emitter.off(eventName)
      return
    }
    Object.values(Marker.EVENT_TYPE).forEach((item) => {
      this.emitter.off(item)
    })
  }
}
